import { OverlayRef } from '@angular/cdk/overlay';
import { EventEmitter, TemplateRef, Type } from '@angular/core';

export type OnClickCallback<T> = ((instance: T) => (false | void | {}) | Promise<false | void | {}>);

export type ModalType = 'default' | 'confirm'; // Different modal styles we have supported

export type ConfirmType = 'confirm' | 'info' | 'success' | 'error' | 'warning'; // Subtypes of Confirm Modal

// Public options for using by service
export interface ModalOptions<T = any, R = any> { // tslint:disable-line:no-any
  apesModalType?: ModalType;
  apesVisible?: boolean;
  apesZIndex?: number;
  apesWidth?: number | string;
  apesWrapClassName?: string;
  apesClassName?: string;
  apesStyle?: object;
  apesIconType?: string; // Confirm Modal ONLY
  apesTitle?: string | TemplateRef<{}>;
  apesContent?: string | TemplateRef<{}> | Type<T>;
  apesComponentParams?: Partial<T>;
  apesClosable?: boolean;
  apesMask?: boolean;
  apesMaskClosable?: boolean;
  apesMaskStyle?: object;
  apesBodyStyle?: object;
  apesFooter?: string | TemplateRef<{}> | Array<ModalButtonOptions<T>>; // Default Modal ONLY
  apesGetContainer?: HTMLElement | OverlayRef | (() => HTMLElement | OverlayRef); // STATIC
  apesAfterOpen?: EventEmitter<void>;
  apesAfterClose?: EventEmitter<R>;

  // --- Predefined OK & Cancel buttons
  apesOkText?: string;
  apesOkType?: string;
  apesOkLoading?: boolean;
  apesOnOk?: EventEmitter<T> | OnClickCallback<T>; // Mixed using ng's Input/Output (Should care of "this" when using OnClickCallback)
  apesCancelText?: string;
  apesCancelLoading?: boolean;
  apesOnCancel?: EventEmitter<T> | OnClickCallback<T>; // Mixed using ng's Input/Output (Should care of "this" when using OnClickCallback)
}

// tslint:disable-next-line:no-any
export interface ModalOptionsForService<T = any> extends ModalOptions<T> {
  // Limitations for using by service
  apesOnOk?: OnClickCallback<T>;
  apesOnCancel?: OnClickCallback<T>;
}

// tslint:disable-next-line:no-any
export interface ModalButtonOptions<T = any> {
  label: string;
  type?: string;
  shape?: string;
  ghost?: boolean;
  size?: string;
  autoLoading?: boolean; // Default: true, indicate whether show loading automatically while onClick returned a Promise

  // [NOTE] "componentInstance" will refer to the component's instance when using Component
  show?: boolean | ((this: ModalButtonOptions<T>, contentComponentInstance?: T) => boolean);
  loading?: boolean | ((this: ModalButtonOptions<T>, contentComponentInstance?: T) => boolean); // This prop CAN'T use with autoLoading=true
  disabled?: boolean | ((this: ModalButtonOptions<T>, contentComponentInstance?: T) => boolean);
  onClick?(this: ModalButtonOptions<T>, contentComponentInstance?: T): (void | {}) | Promise<void | {}>;

  // tslint:disable-next-line:no-any
  [key: string]: any;
}
